layui.define(["search","table","layer","button","laydate",'form'],function(exports) {
    const table = layui.table;
    const layer = layui.layer;
    	
    //class 讲解
    //static 定义静态方法，一般用来提供一些工具方法，让方法只能通过实例调用
    //get set  类型对象的的get和set属性
    //static get  可以结合使用
    class Grid {
        constructor (id,opt,xml){
            this.$id = id;
            if($("#"+id).length<1){return $.alert(0,"容器id不存在");}
            if($("#"+id).data("data") && (typeof opt != "object"  || !opt) ){
                this.$xml =$("#"+id).data("xml");
                this._init($("#"+id).data("data"));
            }else if(typeof opt == "object"){
                this.$xml =xml;
                this._init(opt);
            }else{
                this.$xml = opt;
                this._getConfig(id);
            }
        }
        
        _getConfig(id){
            $.ajaxs(__webConfig__.xw_grid.option_url,{
                id: id,
                url: $.getRequest("url")
            },(res)=>{
                this._init(res.data);
            },false,false);
        }
        
        _init (opt){
            let $th=this;
            $th.option = opt || {};
            $th.option.cols = $th.cols;
            $th.$id = opt.id;
            $th.tableId = `xw_${$th.randomString}`;
            $th.toolbarId = `xw_${$th.randomString}`;
            $th.$el = $(`#${$th.$id}`);
            $th.$el.html( $th.getHtml );
            $th.$grid = table.render( $th.defaults );
            $th.$data = [];
            $th._initStyle();
            $th._initEvent();
            $th.tableLoadIndex = 1;
            //搜索控件
            if($th.option.search && $th.option.search.query){
                $th.option.search.id = $th.$id +"Search";
                $th.$search = layui.search.render($th.option.search);
                $th.$search.query((res,e)=>{ 
                    $th.load($th.___queryFront ? $th.___queryFront(res,e) : res);
                });
                $(function(){ $th.$search.clickQuery();  });
            }
        }
        
        get defaults (){ 
            let $th=this;
            let gridConfig = (window.__webConfig__ && __webConfig__.xw_grid) || {};
            let defaults={
                id: $th.tableId,
                title: $th.option && $th.option.title || '数据列表',
                elem: '#'+$th.tableId,
                url:__webConfig__.xw_grid.data_url,
                data:[],
                method:'post',
                where:{
                    keyWord: JSON.stringify({
                        id:this.$id,
                        order:null,
                        filter:$th.$filter
                    }),
                    url:$.getRequest("url")
                },
                request: {pageName: 'pageIndex',limitName: 'pageSize' },
                totalRow:false,//是否开启合计行区域
                toolbar: "",//加载头部
                btns:[],
                size: 'sm', //小尺寸的表格
                //---树
                isTree:0,//是否树
                treeId:'',//树形id字段名称
                treeUpId:'',//树形父id字段名称
                treeName:'',//以树形式显示的字段
                //----
                page: {
                    layout:['count','prev', 'page', 'next',"limit","skip"],
                    prev:"上一页",
                    next:"下一页",
                    first:"首页",
                    last:"尾页",
                    groups:4,
                },
                cellMinWidth:60,//全局定义所有常规单元格的最小宽度
                limit: gridConfig.limit || 50,  
                limits: gridConfig.limits || [50,100, 300, 500],
                loading:true,
                autoSort: false,		//禁止前端排序
                defaultToolbar:[],//['filter', 'print', 'exports']
                parseData:function (res){
                    var data=res.data || {total:0,data:[]};
                    return {
                        "code": res.code, //解析接口状态
                        "msg": res.msg, //解析提示文本
                        "count":data.total, //解析数据长度
                        "data": data.data //解析数据列表
                    };  
                },
                cols:[],
                done:function(res){
                    if($th._loadSuccess){$th._loadSuccess(res)}
                    if($th.loadSuccessFn){$th.loadSuccessFn(res)}
                }
            }
            if(this.option.showHead == "false" || this.option.showHead == false){
                this.option.toolbar= false;
            }else{
                this.option.toolbar= '#'+$th.toolbarId;
            }
            if( this.option.showPage == "false" || this.option.showPage == false){
                defaults.page=false;
                defaults.limit=-1;
            }
            if(this.option.cols[0] && this.option.cols[0][0]){
                $.each(this.option.cols,function(e,ietm){
                    $.each(ietm,function(i,o){
                        if( o.total == "true" || o.total == true){  $th.option.totalRow=true; }
                    });
                });
            }
            if( this.option.pageMode === 2){
                defaults.page.layout = ['count','prev',  'next' ,'limit',"skip"];
            }
            if( this.option.data ){ defaults.url = false }
            this.option.isTree = this.option.isTree && this.option.isTree != 'false';
            return $.extend(true, {}, defaults, this.option);
        }
        
        get cols(){
            let $th = this;
            let $option = $th.option;
            let $cols = $th.option.cols, $cols1=[], $cols2=[], $cols3=[];
            
            //获取表头的总层级
            let rowspan = 1;
            $cols[0].forEach(function(h){
            	if(h.children && h.children[0]){
            		rowspan=2;
            		h.children.forEach(function(k){
            			if(k.children && k.children[0]){
            				rowspan=3;
            			}
            		});
            	}
            });
            
            //遍历出每一行
            $cols[0].forEach(function(h){
            	$cols1.push( $th._initColsAttr(h,rowspan,"h") );
            	h.children.forEach(function(k){
            		$cols2.push($th._initColsAttr(k,rowspan,"k"));
            		k.children.forEach(function(g){
            			$cols3.push($th._initColsAttr(g,rowspan,"g"));
            		});
            	});
            });
            
            //添加复选框或索引
            let cols = [], arr = [];
            if($th.option.showRowIndex != "false" && $th.option.showRowIndex != false ){
                arr.push({
                	field:"_index",type: 'numbers',title:'#', fixed: 'left',
                	totalRowText:"合计:",
                	rowspan:rowspan
                });
            }
            if($th.option.multiSelect == "false" || $th.option.multiSelect == false ){
            	let hide =  ($th.option.mergeCheck !=='false' && $th.option.mergeCheck);
                arr.push({field:"_check",type:'radio',fixed: 'left',hide:!hide,rowspan:rowspan});
            }else{
                arr.push({field:"_check",type:'checkbox',fixed:'left',rowspan:rowspan})
            }
            
            cols.push(arr.concat($cols1));
            if($cols2[0])  cols.push($cols2);
            if($cols3[0])  cols.push($cols3);
            return cols;
        }
        
        //设置控件初始样式
        _initStyle (){
            this.$el.addClass("xw__grid").css("position","relative");
            var height= this.$el.attr("height");
            var padding= this.$el.attr("padding");
            if(height){
                if(height<0){
                    this.$el.css("height","calc(100% - "+-height+"px)");
                }else{
                   this.$el.outerHeight(height); 
                }
            }else if(this.$el.attr("style").indexOf("height") == -1){
                this.$el.outerHeight("100%");
            }
            if(padding){
                this.$el.css("padding",padding+"px");
            }
            
            //初始化搜索控件布局
            this._initGridBody();
        }
        
        //初始化搜索控件布局
        _initGridBody(){
            let $search = this.$el.find('.xw__grid_search_body');
            if( $search.length ){
                setTimeout(()=>{
                   let ht = $search.outerHeight();
                   this.$el.find('.xw__grid_grid_body').css('height',`calc(100% - ${ht}px)`);
                }, 0);
            }
        }
        
        //设置表头的合并
        _setColsColspanAndRowspan(h,rowspan,type){
        	let colspan=1;
        	if(h.children && h.children[0] && type=="h"){
        		rowspan = (rowspan - 2) || 1;
        		colspan += h.children.length - 1 || 1;
        		h.children.forEach(k=>{
        			if(k.children &&k.children[0]){
        				colspan += k.children.length - 1 || 1;
        			}
        		});
        	}
        	if(!h.children || !h.children[0] && type=="k"){
        		rowspan = rowspan - 1;
        	}else if(h.children && h.children[0] && type=="k"){
        		rowspan = rowspan - 2;
        		colspan += h.children.length - 1 || 1;
        	}
        	if(!h.children || !h.children[0] && type=="g"){
        		rowspan = rowspan - 1;
        	}
        	return {rowspan:rowspan,colspan:colspan}
        }
        
        //获取模板
        _getTpl(that,data,type){
        	let gridConfig = (window.__webConfig__ && __webConfig__.xw_grid) || {};
			let defaultAcc = gridConfig.numberAcc  || 2;
			let enabledPermil = gridConfig.enabledPermil === false ? false : true;
			let value = data.data[data.fieid];
			let item=data.item;
			let dataType = item.dataType;
			let acc = data.item.acc === 0 ? 0 : (data.item.acc || defaultAcc);
			let html  = "";
			if(dataType == "number"){
				value = Number(value).toFixed(acc);
				if(String(item.enabledPermil) !="false" && enabledPermil){
					value = $.commafy(value);
				}
			}
			if(type==2) return value;
			switch(dataType){
			    case "texts":
			        html = $.map(item.options,function(h){
			            if(h.value==value){ 
			            	return `<em style="color:${h.color};">${h.label}</em>`
			            }
			        })[0];
			    break;
				case "text":
                case "number":
	        		html = `
	        			<input type="text" ${dataType}-type 
	        				class="xw_table_text text-${data.item.align}"
	                        value="${ value }"
	                        placeholder="${item.placeholder || ''}" 
	                        max="${ item.max }"
	                        min="${ item.min }"
	                        max-length = "${ item.maxLenght }"
	                        enabledpermil="${enabledPermil}"
	                        acc="${ acc }"
	                       ${item.vType ? "dataType="+item.vType  : '' }
	                       	ignore = "${item.ignore && item.ignore == "true" ? 'ignore' : '' }"
	                    />
	        		`;
				break;
                case "select":
                	let options = item.options ? $.trim(item.options.map(h=>{
                    let selected = String(value).indexOf(h.value) != -1 ?  'selected' : '';
	                    return `<option value="${$.trim(h.value)}"  ${selected}>${h.label}</option>`;
	                }).join("")) : '';
	               	html =` 
	               		<select class='layui-input xw_table_select' 
	               			lay-ignore
	                        ${item.vType ? "dataType="+item.vType  : '' }
	                       	ignore = "${item.ignore && item.ignore == "true" ? 'ignore' : '' }"
	                    >${ options}</select>`;
                break;
                case "datetime":
                	value=$.getDate(item.format || 'yyyy-MM-dd HH:mm' ,value);
	               	html =` 
	                	<input readonly datetime="datetime"
	                		class="layui-input xw_table_datetime text-${data.item.align}" 
	                        format="${item.format || 'yyyy-MM-dd HH:mm'}"
	                        value="${value}" 
	                        name="${item.field}" 
	                        ${item.vType ? "dataType="+item.vType  : '' } 
	                       	ignore = "${item.ignore && item.ignore == "true" ? 'ignore' : '' }"
	                        min="${item.min}"
	                        max="${item.max}"
	                	/>
	                `;
	            break;
                case "link":
	        		String(data.item.onClick).split(";").forEach(function(h){
	        			var isShow = that._getEventIf(h,data);
	        			var isShowStyle = isShow ? '' : 'visibility: hidden;';
        				html += `
		        			<a href="${ data.data[data.item.href] || 'javascript:void(0);' }"  class="link" 
		        				style="margin:0 3px;${isShowStyle}" 
		        				on-click="${that._getEvent(h,data)}"
		        				${ data.data[data.item.href] ?  "target='_target'" : ""}
		        			>${that._getEventTitle(h,data)}</a>
	        			`;
	        		});
	        	break;
	        	case "button":
	        		if(data.item.buttons[0]){
	        			var itemBtns = data.item.buttons.map(function(h){
	        				h.title = data.data[h.title] !== undefined ? data.data[h.title] : h.title;
	        				if(h.show){
	        					if(String(h.show).indexOf("!=") != -1){
	        					    var fid = $.trim(String(h.show).split('!=')[0]);
		        					h.show = data.data[fid] != $.trim(String(h.show).split('!=')[1]);
		        				} else if(String(h.show).indexOf("=") != -1){
	        					    var fid = $.trim(String(h.show).split('=')[0]);
		        					h.show = data.data[fid] == $.trim(String(h.show).split('=')[1]);
		        				}else{
		        					h.show = data.data[h.show] !== undefined ? data.data[h.show] : h.show;
		        				}
	        				}
	        				h['on-click'] = that._getEvent(h.onClick,data); h.onClick = '';
	        				return h;
	        			});
	        			html += `${layui.button.getBtn(itemBtns,false)}`;
	        		}else{
	        			String(data.item.onClick).split(";").forEach(function(h){
		        			var isShow = that._getEventIf(h,data);
		        			var isShowStyle = isShow ? '' : 'visibility: hidden;';
	        				html += `
			        			<a class="layui-btn  layui-btn-sm" 
			        				style="${ that._getStyle(h) } ;${isShowStyle}"
			        				on-click="${that._getEvent(h,data)}" 
			        			>${that._getEventTitle(h,data)}</a>
		        			`;
		        		});
	        		}
	        	break;
	        	case "switch":
	        	    var layText = data.item.layText || '';
	        	    var isChecked = value == 1 || value == 'true' ? 'checked' : '';
	        	    String(data.item.onClick).split(";").forEach(function(h){
                        html = `
                            <span lay-filter='xw_grid_switchs'>    
                            <input type="checkbox" lay-skin="switch" lay-filter='xw_grid_switch'
                                lay-text="${layText}"
                                value="${value}"
                                name="${item.field}"
                                reverse="${item.reverse || false}"
                                on-click="${that._getEvent(h,data)}"
                                ${ isChecked }  
                            />
                            </span>
                        `;
                    });
                break;
                case "imgs":
                	var vals = String(value).split(",").map(function(h){
                       	var val = h.replace(/\\/g,"/");  
                		return (val.indexOf('http') == -1 ? '/' : '') + val; 
                    });
                	html = `
                		<div class="file-img"
                			style="background-image:url(${vals[0]});"
                			onclick="$.photoImg('${vals.join(',')}');"
                		></div>
                	`;
                	if( $(`#${this.$id}_style_img`).length == 0 ){
                		$('body').append(`
	                		<style type="text/css" id="${this.$id}_style_img">
								#${this.$id} .layui-table-view .layui-table td .layui-table-cell{
									height: 50px;
								    line-height: 50px;
								}
							</style>
	                	`);
                	}
                break;
                case "search":
                	var val = String(value).split(',').map(h=>{
                    	let html= `<span><u onclick="${item.onValClick || item.onClick}" >${h}</u></span>`;
                    	if(String(item.showCloseBtn)!="false" && item.isEdit !="false" && h){
                    		html =  `
	                        	<span>
		                        	<u onclick="${item.onValClick || item.onClick}" >${h}</u>
		                        	<sup class="span-close">x</sup>
	                        	</span>	
	                        `;
                    	}
                    	return html;
                    }).join('');
	                html =`
                        <div class="select-search-body" style="margin-top: 2px;">
                            <div class="select-search-input" type="search"
                            	form-dataType="search"
                            	onValClick="${item.onValClick || item.onClick}"
                            	showclosebtn="false"
                                name="${item.field}" 
                                edit="${item.edit}" 
                                data-value="${value}"
                                ${item.vType ? 'dataType=chooseBox'  : '' }
                                ignore = "${item.ignore && item.ignore == "true" ? 'ignore' : '' }"
                                errormsg = "${item.errormsg || '格式不正确'}"
                            >${val}</div>
                            <button type="button" class="select-search-icon" 
                            	onclick="if($(this).prev().attr('edit')!='false'){${item.onClick}}"
                            ><i class="iconfont">&#xe651;</i></button>
                        </div>
                    `;
                break;
			}
			return $.removeTrimEnter(html); 
        }
        
        //初始化每一行的属性配置
        _initColsAttr(h,rowspan,type){
        	var that = this;
        	var colspanAndRowspan =this._setColsColspanAndRowspan(h,rowspan,type);
        	h.rowspan = colspanAndRowspan["rowspan"];
        	h.colspan = colspanAndRowspan["colspan"];
            if( 
                h.isEdit === true
                || h.isEdit == "true"
                || h.templet
                ||  ['link','imgs','button','switch','texts'].indexOf(h.type) != -1
            ){
            	h.templet = h.templet ? eval(h.templet) : function(d){
            		return that._getTpl(that,d) 
            	};
            }else if(h.color){
            	h.templet = function(d){
            		if(h.color.indexOf('?')!=-1){
            			var db = d.data; 
            			var costr = h.color.replace(" eq ","==").replace(" neq ","!=")
            						.replace(" gt ",">").replace(" egt ",">=")
            						.replace(" lt ","<").replace(" elt ","<=");
            			return "<p style='color:"+eval( costr )+";'>"+that._getTpl(that,d,2)+"</p>";
            		}
            		return "<p style='color:"+h.color+";'>"+that._getTpl(that,d,2)+"</p>";
            	};
            }
            if(h.total == true || h.total == "true") h.totalRow = true;
            h.sort= String(h.sort) == "true" ? true : false;
            h.dataType=h.type;
            h.cellMinWidth=100;
            h.type="normal";
            if($.isNumeric(h.width)){
                h.width=Number(h.width);
            }else if(h.width=="auto"){
                h.width="";
            }
            return h;
        }
        
        //获取样式
        _getStyle(Event){
        	var edittype = String(Event);
            var param = "";
            var $style = "";
            var leftIndex = edittype.indexOf("{");
            var rightIndex = edittype.indexOf("}");
            if (leftIndex != -1) {
                param = $.trim(edittype.substring(leftIndex + 1, rightIndex)).split(',').join(';');
                $style = param;
            }
            return $style;
        }
        
        //获取事件
        _getEvent(Event, data){
        	var edittype = String(Event);
            var eventName = "";
            var param = "";
            var $event = "";
            var leftIndex = edittype.indexOf("(");
            var rightIndex = edittype.indexOf(")");
            if (leftIndex != -1) {
                eventName = $.trim(edittype.substring(0, leftIndex));
                eventName = eventName.replace(/this/g,this.$id);
                param = $.trim(edittype.substring(leftIndex + 1, rightIndex)).split(',');
                param = $.map(param, function (h) {
                	if(h.indexOf("'") !== -1 ){
                		return h;
                	}else{
                		return "'" + (data.data[h] != undefined ? data.data[h] : h) + "'"; 
                	}
                }).join(',');
                $event = eventName + "(" + param + ")";
            }
            return $event;
        }
        
        //获取事件标题
        _getEventTitle(Event, data){
        	var $eventFn = String(Event);
            var leftIndex = $eventFn.indexOf("[");
            var rightIndex = $eventFn.indexOf("]");
            if(leftIndex != -1 && rightIndex  != -1 ){
            	return $.trim($eventFn.substring(leftIndex + 1, rightIndex)) || data.data[data.fieid];
            }else{
            	if(data.data[data.fieid] || data.data[data.fieid] ==0){
            		return data.data[data.fieid];
            	}else{
            		return "查看详情";
            	}
            }
        }
        
        //获取判断
        _getEventIf(Event, data){
        	var $eventFn = String(Event);
            var leftIndex = $eventFn.indexOf("?");
            var rightIndex = $eventFn.indexOf("?",leftIndex + 1);
            if(leftIndex != -1 && rightIndex  != -1 ){
            	var str = $.trim($eventFn.substring(leftIndex + 1, rightIndex));
        		var fields = str.split('=');
        		if(data.data[ fields[0] ] == fields[1]){
        			return true;
        		}else{
        			return false;
        		}
            }else{
            	return true;
            }
        }
        
        get getHtml() {
            let $th=this;
            let html = '';
            if($th.option.search && $th.option.search.query){
                html += `
                    <div class='xw__grid_search_body'><div id='${$th.$id +"Search"}'></div></div>
                    <div class='xw__grid_grid_body' >
                `;
            }
            let bodyHeight= 35 * ($th.option.cols.length || 1);
            let clickRowBg = "";
            if(String($th.defaults.showClickRowBg) == "false"){
                clickRowBg = `
                    #${$th.$id} .layui-table tbody tr:hover,
                    #${$th.$id} .layui-table-hover {background: none; }
                    #${$th.$id} .layui-table-click { background: none !important;}
                `;
            }
            html += ` 
                <style type="text/css">
                	#${$th.$id} .layui-table-body{height: calc(100% - ${bodyHeight}px);}
                	#${$th.$id} .layui-table-box{ height: calc(100% - ${$th.boxHeight}px);} 
                	${clickRowBg}
                </style>
                <script type="text/html" id="${$th.toolbarId}"> 
                    <span style="float:left;"> 
                    	${$th.defaults.title} 
                    	<i class="layui-icon layui-icon-refresh-3" ></i>
                    </span>
                    <div style="float:left;margin-left:20px;" class="xw_grid_head"></div>
                    <div style="float:right;line-height: 32px;margin-top: 5px;">
                        ${layui.button.getBtn($th.defaults.btns)}
                    </div>
                </script>
                <table class="layui-hide" id="${$th.tableId}" lay-filter="${$th.tableId}"></table>
            `;
            if($th.option.search && $th.option.search.query){
                html += `</div> `;
            }
            return $.removeTrimEnter(html);
        }
        
        //初始化事件
        _initEvent(){
            var $th=this;
            //重置表格大小
            $th._resize();
            //绑定输入框初始事件
            $.bindInputEvent($th.$el);
            //单击行
            table.on('row('+$th.tableId+')', function(obj){
                if($th.option.rowClick){
                    clearInterval($th.$__timeoutRowClick); 
                    $th.$__timeoutRowClick=setTimeout(function(){
                        eval($th.option.rowClick); 
                    },150);
                }
            });
            //双击行
            table.on('rowDouble('+$th.tableId+')', function(obj){
                if($th.option.rowDouble){ eval($th.option.rowDouble); }
            });
            //监听排序事件 
            table.on('sort('+$th.tableId+')', function(obj){
            	$th.$grid.refresh({
            		keyWord: JSON.stringify({
	                    id:$th.$id,
	                    filter:$th.$filter,
	                    order:"order by "+ obj.field + ' ' + obj.type
                	}),
                	url:$.getRequest("url")
            	});
			});
			if(!$th.tableLoadIndex){
				//链接和按钮点击事件
				$th.$el.on('click','a.link,a.layui-btn,button.link,button.layui-btn',function(e){
					var clicks = $(this).attr('on-click');
					if(clicks){
						setTimeout(function(){ eval(clicks) },10);
					}
				});
	            //绑定下拉事件
	            $th.$el.on('change','.xw_table_select',function(e){
	                let field=$(this).parents("td").data().field;
	                let index=$(this).parents("tr").data().index;
	                $th.update(index, {[field]:$(this).val()},$(this));
	                if($th.$inputCallbackFn){ 
	                    $th.$inputCallbackFn(
	                        $(this),
	                        { field:field, index:index, value:$(this).val() },
	                        $th.getObj().cache[index]
	                    )
	                }
	        	});
	        	//刷新按钮
	        	$th.$el.on("click",".layui-icon-refresh-3",function(){
	            	$th.load();
	            });
	            //监听输入-回调-更新数据
	            $th.$el.on('input propertychange','input.xw_table_text',function(e){
	                let field=$(e.target).parents("td").data().field;
	                let index=$(e.target).parents("tr").data().index;
	                $th.update(index, {[field]:$(e.target).val()},$(e.target));
	                if($th.$inputCallbackFn){ 
	                    $th.$inputCallbackFn(
	                        $(e.target),
	                        {field:field,index:index,value:$(e.target).val() },
	                        $th.getObj().cache[index]
	                    )
	                }
	            });
        	}
			$(`#${$th.toolbarId}`).remove();
        }
        
        //绑定时间事件
        _initDatetime(){
        	var $th=this;
            if(this.$el.find(".xw_table_datetime").length!=0){
                $.each(this.$el.find(".xw_table_datetime"), function(index,o) {
                    let field=$(o).parents("td").data().field;
                    let dataIndex=$(o).parents("tr").data().index;
                    layui.laydate.render({ 
                        elem: o,
                        format: $(o).attr("format") || 'yyyy-MM-dd', //可任意组合 yyyy-MM-dd HH:mm:ss
                        position: 'abolute',
                        min: !$(o).attr("min")  ?  "1900-1-1" : $(o).attr("min"),
                        max: !$(o).attr("max")  ?  "2199-12-31" : $(o).attr("max"),
                        showBottom:true,
                        trigger: 'click', //呼出控件的事件
                        type: $th._getFormat($(o).attr("format")),
                        done: function(value, date, endDate){
                        	$th.update(dataIndex, {[field]:value },$(o));
                        	$(o).blur();
                        	if($th.$inputCallbackFn){
                        		setTimeout(function(){ 
                                	$th.$inputCallbackFn(
                                	    $(o), 
                                	    { field:field, index:dataIndex, value: value},
                                	    $th.getObj().cache[dataIndex]
                                	)
                            	},5)
                        	}
                        }
                    });
                });
            }
        }
        
        //获取时间格式
        _getFormat(format){
            let _format='date';
            if(format.indexOf("d") ==-1 && format)
                _format='month';
            if(format.indexOf("M") ==-1 && format)
                _format='year';
            if(format.indexOf("H") !=-1)
                _format='datetime';
            return _format;
        }
        
        //监听容器大小
        _resize(){
            var $th=this;
            var dom = document.getElementById($th.$id); 
            var $width = dom.clientWidth;
            var $height = dom.clientHeight;
            $th.resize();
            setInterval(function  () {
                var _width = dom.clientWidth;
                var _height = dom.clientHeight;
                if( _width != $width || _height != $height){
                    if(_width > 0 && $(":animated").length==0){
                        $th.resize(false);
                        $width= _width;
                        $height=_height;
                    }
                }
            },50);
        }
        
        //计算高度
        get boxHeight (){
            let height= 118 + 6;
            let defaults = this.defaults;
            if(defaults.showHead == "false" || defaults.showHead == false ){ 
            	height = height - 41 + 6; 
            }
            if(defaults.totalRow == "false" || defaults.totalRow == false ){ 
            	height = height - 31 - 6;
            }
            if(defaults.showPage == "false" || defaults.showPage==false){
            	height = height -  41;
            }
            return height;
        }
        
        //获取随机编码
        get randomString(){
            var len = len || 32;
            var $chars ="ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
            var maxPos = $chars.length;
            var pwd = '';
            for (let i = 0; i < len; i++) { pwd += $chars.charAt(Math.floor(Math.random() * maxPos));}
            return pwd;
        }
        
        //合并单元格
        _mergeCell(){
            var $th=this;
            var tableBox =$('#'+$th.tableId).next().children('.layui-table-box'),
            $main = $(tableBox.children('.layui-table-body')
                        .children('table')
                        .children('tbody')
                        .children('tr')
                        .toArray().reverse()),
            $fixLeft = $(tableBox.children('.layui-table-fixed-l')
                        .children('.layui-table-body')
                        .children('table')
                        .children('tbody')
                        .children('tr')
                        .toArray().reverse()),
            $fixRight = $(tableBox.children('.layui-table-fixed-r')
                        .children('.layui-table-body')
                        .children('table')
                        .children('tbody')
                        .children('tr')
                        .toArray().reverse()),
            mergeRecord = {};
            let mergeIndex = $th.option.mergeIndex !="false" ? $th.option.mergeIndex :  false;
            let mergebox = $th.option.mergeCheck !="false" ? $th.option.mergeCheck :  false;
            var cols = $th.option.cols[0].concat($th.option.cols[1] || []);
            var cols = cols.concat($th.option.cols[2] || []);
            var cols = $.map($(tableBox).find(".layui-table-body tr").eq(0).find("td"), function(h) {
                var obj = $(h).data();
                $.each(cols, function(index,o) {
                    if(obj.field == o.field && o.merge !='false'){
                        obj.merge = o.merge || false;
                    }
                    if(obj.field === "_index" && mergeIndex){
                    	obj.merge = mergeIndex;
                    }
                    if(obj.field === "_check" && mergebox){
                    	obj.merge = mergebox;
                    }
                });
            	return obj;
            });
            for (let i = 0; i < cols.length; i++) {
                var item3 = cols[i], field=item3.field;
                if (item3.merge) {
                    var mergeField = [field];
                    if (String(item3.merge) !== "true") {
                        if (typeof item3.merge == 'string') {
                            mergeField = [item3.merge]
                        } else {
                            mergeField = item3.merge
                        }
                    }
                    var key = item3.key;
                    mergeRecord[key] = {mergeField: mergeField, rowspan:1}
                }
            }
            
            $main.each(function (i) {
                for (var item in mergeRecord) {
                    if (i==$main.length-1 || isMaster(i, item)) {
                        var rowspan = mergeRecord[item].rowspan;
                        $(this).children('[data-key="'+item+'"]').attr('rowspan', rowspan);
                        $fixLeft.eq(i).children('[data-key="'+item+'"]').attr('rowspan', rowspan);
                        $fixRight.eq(i).children('[data-key="'+item+'"]').attr('rowspan', rowspan);
                        mergeRecord[item].rowspan = 1;
                    } else {
                        $(this).children('[data-key="'+item+'"]').attr('rowspan', 0).hide();
                        $fixLeft.eq(i).children('[data-key="'+item+'"]').attr('rowspan', 0).hide();
                        $fixRight.eq(i).children('[data-key="'+item+'"]').attr('rowspan', 0).hide();
                        mergeRecord[item].rowspan +=1;
                    }
                }
            });
            
            function isMaster (index, item) {
                var cache = layui.table.cache[$th.$id];
                var mergeField = mergeRecord[item].mergeField;
                var dataLength = cache.length;
                for (var i=0; i<mergeField.length; i++) {
                    if (cache[dataLength-2-index][mergeField[i]]
                        !== cache[dataLength-1-index][mergeField[i]]) {
                        return true;
                    }
                }
                return false;
            }
        }
        
        //初始化form事件
        _initForm(){
            //layui.form.render(null,null,'#'+this.$id);
            layui.form.render('checkbox','xw_grid_switchs',`#${this.$id} `);
            layui.form.on('switch(xw_grid_switch)', e=>{
                let clicks = $(e.elem).attr('on-click');
                setTimeout(()=>{
                    if(clicks){  	
                    	eval(clicks)  
                    }else{
                    	let ids = this.getSelectedColumnValue(this.defaults.key);
                    	let reverse = $(e.elem).attr('reverse')  == 'true';
                    	let value = e.elem.checked ? 1 : 0;
                    	if(reverse){ value =  value == 1 ? 0 : 1;}
                    	this.updateField(ids,e.elem.name, value, false);
                    	//this.update({id:ids},{ [e.elem.name]: value}); 
                    }
                },10)
            });  
        }
        
        //加载成功
        _loadSuccess(obj){
            this.$data = obj.data;
            this.setHeadHtml(this.HeadHtml);
            this._mergeCell();
            this._initDatetime();
            this._initForm();
            this._defaultSelected();
        }
        
        //默认选中
        _defaultSelected(){
        	let $th=this;
            let keyName= String($th.defaults.key).split(",")[0];
            let isRows =  $th.rows && $th.rows[0];
            if(isRows && $th.$data && ($th.$data.length-$th.rows.length) == 1 && keyName){
            	let data =$.map($th.$data,function(h){  return h[keyName] });
            	let rows = $.map($th.rows,function(h){  return h[keyName] });
            	let $obj=this.$grid.getObj();
				let dd = $.grep(data, function(n,i){
				  	return jQuery.inArray(n, rows) < 0;
				});
				if(dd[0]){
					$th.$data.forEach( h => {
	            		if(h[keyName] == dd[0]){
	            			$th.setSelected(h.LAY_TABLE_INDEX);
	            			$obj.selectedMergeCheckbox($obj.layMain.find('tr').eq(h.LAY_TABLE_INDEX) ,true);
	            		}
	            	});
				}
            }else if($th.selectRow && $th.$data && $th.$data[0] && keyName){
            	$th.$data.forEach( h => {
            		if(h[keyName] && h[keyName] == $th.selectRow[keyName]){
            			$th.setSelected(h.LAY_TABLE_INDEX);
            		}
            	});
            }
           
            $th.selectRow=null;
            $th.rows = null;
        }
        
        queryFront(fn){
            this.___queryFront = fn;
        }
        
        //设置选中
        //number/Object
        // Object = {field:"id",value:"2"}
        setSelected(index){
            let $obj=this.$grid.getObj();
            if($.isPlainObject(index)){
                $obj.cache.forEach((h,i)=>{
                    if(h[index.field] && h[index.field] == index.value){
                        $obj.setSelected(i,true);    
                    }
                });
            }else{
                let indexs = String(index).split(",");
                if(indexs.length>1){
                    indexs.forEach(i=>{
                        $obj.setSelected(i,true);    
                    });
                }else{
                    $obj.setSelected(index,false);    
                }
            }
            //定位滚动条到对应行
            this.$el.find('.layui-table tr.layui-table-click').eq(0)
                .attr("tabindex","0")
                .focus()
                .blur()
                .removeAttr("tabindex");
        }
        
        //加载成功回调
        loadSuccess (fn){
            this.loadSuccessFn=fn;
        }
        
        //监听输入
        input(callbackFn){
            this.$inputCallbackFn=callbackFn;
        }
        
        //设置头部html
        setHeadHtml(html){
            this.HeadHtml=html;
            if(html) this.$el.find(".xw_grid_head").html(html);  
        }
        
        //重新加载配置
        reLoadConfig(id,filter){
            if(filter === true){
                this.$filter = [];
            }else if($.isArray(filter)){
                this.$filter = filter || [];
            }
            this._getConfig(id);
            this.load();
        }
        
        //加载
        load(filter){
        	let selectRow = this.getSelectedRows();
        	this.selectRow =  selectRow.length == 1 ? selectRow[0] : false;
        	this.rows =  this.getRows();
            this.$filter = filter || this.$filter;
            let Obj = this.getObj();
        	Obj.sortKey =null;
        	Obj.layHeader.find('th').find('.layui-table-sort').removeAttr('lay-sort');
            if(this.defaults.url===false){
               Obj.config.url="";
               Obj.reload({data:this.$filter});
            }else{
                this.$grid.refresh({
                	keyWord: JSON.stringify({
	                    id:this.$id,
	                    filter:this.$filter
	                }),
	                url:$.getRequest("url")
                });
            }
        }

        // 静默 加载
        silentLoad(filter){
        	this.$grid.config.loading = false;
			this.load(filter);
            this.$grid.config.loading = true;
        }
        
        //更新数据行  index = 1 / {id:"46"}  , data = {age: 123,name: '1'}
        update (index,data,that) {
            let $th=this;
            let a = $th.$grid.getObj();
            let dataIndex = index;
            if("object" ===  typeof index){
                $.each(a.cache,function(key,h){
                    layui.each(index, function(e, l) {
                        if(e in h && index[e]==h[e]) {dataIndex =key;}
                    })
                });
            }
            if("string" ===  typeof index &&  index.length>10){
                a.cache.forEach((h,key)=>{
                    if(h['LAY_TABLE_INDEX'] == index){ dataIndex = key; }
                });
            }
            let r = a.cache[dataIndex];
            let e = data || {};
            let i=layui.laytpl;
            layui.each(e, function(e, l) {
                let g={}, tplData;
                $.each(a.config.cols[0],function(index,o){ if(o.field==e){ g=o; }} );
                if(a.config.cols[1]){
                	$.each(a.config.cols[1],function(index,o){ if(o.field==e){ g=o; }});
                }
                if(a.config.cols[2]){
                	$.each(a.config.cols[2],function(index,o){ if(o.field==e){ g=o; }});
                }
                if(r && e in r) {
                    var n,d =$th.$el.find('tr[data-index="'+dataIndex+'"]').children('td[data-field="' + e + '"]');
                    r[e] = l,
                    a.eachCols(function(t, i) { i.field == e && i.templet && (n = i.templet) });
                    var dataConfig = { fieid:g.field, value:r[g.field], data:r, item:g}
                    if(!that && d.find(".xw_table_text").length==0){
                        d.children(".layui-table-cell").html(function() {
                            return n ? function() {
                                return "function" == typeof n ? n(dataConfig) : i($(n).html() || l).render(r)
                            }() : l
                        }());
                    }else{
                        d.find(".xw_table_text").val(l);
                    }
                    d.data("content", l)
                }
            });
            a.renderTotal($th.getRows());//重新计算合计行
        }
        
        //添加行-完善-参2=是否按排序添加 
        addRow(datas,is){
            var $th=this;
            let a=$th.$grid.getObj();
            var data=$th.getRows();
            datas.forEach(h=>{ 
            	if(h.LAY_TABLE_INDEX == undefined){
            		h.LAY_TABLE_INDEX = $.createGuid();
            	}
            	data.push(h);
            });
            a.renderData({data:data},1,data.length,!is);
            a.renderTotal(data);//重新计算合计行
            $th.resize()
            if(!is){$th.$el.find(".layui-table-body").scrollTop(100000000);}
        }
        
        //重置大小
        resize(isHide){
            this._initGridBody();
            this.$grid.getObj().resize(isHide);
        }
        
        //删除数据行  index = 1 / {id:"46"}  
        deleteRow(index){
            let $th=this;
            let a=$th.$grid.getObj();
            let dataIndex = index;
            if("object" ===  typeof index){
                $.each(a.cache,function(key,h){
                    layui.each(index, function(e, l) {
                        if(e in h && index[e]==h[e]) {  dataIndex = key;}
                    })
                });
            }
            if(index  ===  undefined){
            	a.cache.forEach((h,key)=>{
                    if(h.LAY_CHECKED){ dataIndex = key; }
                });
            }
            $th.$el.find('tr[data-index="'+dataIndex+'"]').remove();
            a.cache[dataIndex]=[];
            clearInterval($th.$__timeout);
            $th.$__timeout=setTimeout(function(){
                a.scrollPatch();
                a.setColsWidth();//重置宽度
                a.renderTotal(a.cache);//重新计算合计行
            },10);
        }
        
        //删除选中行--参1=是否跟后台关联，默认关联
        deleteSelectRow(is=true){
            let $th=this;
            var data=$th.$grid.getObj().cache;
            if(!$th.getSelectedRows()[0]){
                $.toast(0,"请选择需要删除的行！");
                return;
            }
            if(is){
                $.confirm("确认删除已选数据？",function(){
                	let keys = String( $th.defaults.key ).split(",");
                    let params = {
                    	data:JSON.stringify( $.map(data,function(h){  
                    		if(h.LAY_CHECKED && h){ 
                    			let obj = {};
                    			for (let key in h) {
                    				if(keys.indexOf(key) != -1 ){
                    					obj[key] = h[key];
                    				}
                    			}
                    			return obj;
                    		}
                   		}) ),
                    	id:$th.$id,
                    	url:$.getRequest("url")
                    }
                    $.ajaxs( __webConfig__.xw_grid.delete_url , params, function(res){
                        $.toast(1,"删除成功！");
                        $th.load();
                        if($.isFunction(is)) { is(res) }
                    })
                });
            }else{
                data.forEach((h,key)=>{
                    if(h.LAY_CHECKED){$th.deleteRow(key);}
                });
            }
        }
        
        //获取所有行
        getRows(){
           let data=this.$grid.getObj().cache;
           let arr=[];
            if(data){
               data.forEach(h => { if(h.length!=0) arr.push(h); });
            }
            return arr;
        }
        
        //获取当前表格对象
        getObj(){
            return this.$grid.getObj();
        }
        
        //获取选中行
        getSelectedRows(){
            var rows = this.getRows();
            var arr=[];
            rows.forEach(h => { if(h.LAY_CHECKED==true) arr.push(h); });
            return arr;
        }
        
        //导出
        exportXls(isPage,isTableExport){
        	let a=this.$grid.getObj();
        	if(isTableExport){
        		table.exportFile(this.$id,this.getRows(), "xls")
        	}else{
        		$.exports( window.__webConfig__.xw_grid.export_excel_url ,{
        			pageSize: (isPage == true && a.config.page ) ?  a.config.page.count  : -1,
        			keyWord: JSON.stringify({
	                    id:this.$id,
	                    filter:this.$filter
	                }),
	                url:$.getRequest("url")
        		});
        	}
        }
        
        //获取汇总行数据
        getTotalRowData(field=''){
            var a=this.$grid.getObj();
            return a.layTotal.find(`tr td[data-field='${field}']`).find(".layui-table-cell").text();
        }
        
        //获取选中列value值，逗号分割
        getSelectedColumnValue(field){
        	var field = field || this.defaults.key;
        	if(field){
        		return $.map( this.getSelectedRows() ,function(h){
        			return h[field] 
        		}).join(',');
        	}
        }
        
        //获取所有列value值，逗号分割
        getAllColumnValue(field){
        	var field = field || this.defaults.key;
        	if(field){
        		return $.map( this.getRows() ,function(h){
        			return h[field] 
        		}).join(',');
        	}
        }
        
        //设置按钮是否显示
        setBtnIsShow(id,isShow){
            let $el= id =="*" ? this.$el.find(".layui-btn") : this.$el.find(id);
            isShow ? $el.show() : $el.hide();
        }
        
        //是否选中
        isSelected(isTisp){
        	let flag =  this.getSelectedRows().length > 0;
        	if(!flag && isTisp !== false){
        		$.toast(0,"请选择数据！");
        	}
        	return flag;
        }
        
        //效验
        verification(){
        	var  $th=this;
            $th.verificationSFlag=false;
            $($th.$el).Validform({
                showAllError: false, //是否全部验证
                tiptype: function  (msg, o, cssctl) {
                    if(o.type==3) {
                        layer.close($th.layerIndex);
                        setTimeout(function  () {
                            $th.layerIndex=layer.tips(msg,$(o.obj),{
                                tips: [1, '#f1355e'],
                                time: 1500,
                                tipsMore: false,
                            });
                        },5);
                    }
                },
                callback: function(data) { //验证成功后是否提交表单！ 直接return false 就不提交
                    $th.verificationSFlag = true;
                    return false;
                }
            });
            $($th.$el).submit();
            return $th.verificationSFlag;
        }
        
        //调整排序
        // type: 1 = 上移 ,  type: 2 = 下移
        adjustSort(type,sortField = 'sort_no'){
        	let $th = this;
	    	let key = $th.defaults.key;
	        let rows = $th.getRows();
	        let selectedRow = $th.getSelectedRows();
	        if( !this.isSelected() ){
	            return;
	        }
	        if( !key ){
	        	$.toast(0,"请在xml上配置主键！");
	            return;
	        }
	        if( selectedRow.length >1 ){
	            $.toast(0,"只能选择一条数据！");
	            return;
	        }
	        let coverId=-1;
	      	rows.forEach(function(h,index){
	      		if(selectedRow[0][key] == h[key]){
	      			if(type==1){
	      				if(rows[index-1]){ coverId = rows[index-1][key]; }
	      			}else{
	      				if(rows[index+1]){ coverId = rows[index+1][key]; }
	      			}
	      		}
	      	});
	        $.ajaxs("/admin/Core/Grid/adjustSort",{
	        	id:$th.$id,
	        	xml: $th.$xml ,
	        	moveId: selectedRow[0][key], 
	        	coverId: coverId,
	        	sortField:sortField
	       	},function(res){
	        	$th.load();
	        });
        }
        
        //更新字段值
        updateField(ids,name,value,isReLoad=true){
        	let $th = this;
	    	let key = $th.defaults.key;
	        if( !key ){
	        	$.toast(0,"请在xml上配置主键！");
	            return;
	        }
	        var ids = ids || this.getSelectedColumnValue(this.defaults.key);
        	$.ajaxs(__webConfig__.xw_grid.update_field || "/admin/core/grid/updateField",{
	        	id:$th.$id,
	        	xml: $th.$xml ,
	        	name: name, 
	        	value: value,
	        	ids:ids
	       	},function(res){
	        	if(isReLoad){
	        	    $th.load();
	        	}else{
	        	   layer.msg('更新成功！',{time: 1000,offset: '80px'});
	        	}
	        },true,false);
        }
        
        //更新行的值
        updateRow(data,ids,isReLoad=true){
        	let $th = this;
	    	let key = $th.defaults.key;
	        if( !key ){
	        	$.toast(0,"请在xml上配置主键！");
	            return;
	        }
	        var ids = ids || this.getSelectedColumnValue(this.defaults.key);
        	$.ajaxs(__webConfig__.xw_grid.update_row || "/admin/Core/Grid/updateRow",{
	        	id:$th.$id,
	        	xml: $th.$xml,
	        	data: JSON.stringify(data), 
	        	ids:ids
	       	},function(res){
	        	if(isReLoad){
	        	    $th.load();
	        	}else{
	        	   layer.msg('更新成功！',{time: 1000,offset: '80px'});
	        	}
	        },true,false);
        }
        
        //更新字段值
        setValue(name,value,desc){
        	let that = this;
        	var ids = that.getSelectedColumnValue(this.defaults.key);
        	if( !ids ){
	        	$.toast(0,"请选择要操作的数据！");
	            return;
	        }
        	if(desc){
			    function yesFn(index){
			        $(".J-changeStatus").validformIn(function(data){ 
			        	var obj = {}; obj[name] = value; obj[desc] = data.desc;
			        	that.updateRow(obj,ids,false);
		                layer.close(index);
			        });
			    }
			    var selcet = that.getSelectedRows();
			    let html= template("grid-tpl-reason",{value: selcet.length == 1? selcet[0][desc] : ''});
			    $.openModalDialog(html,"确认",null,yesFn,["400px","250px"]);
        	}else{
		    	$.confirm("确认操作？", function(index){
	    		  	that.updateField(ids,name,value);
	    		  	layer.close(index);
		    	});
        	}
        }
    }
    
    exports('grid',{ 
        render:function(id,opt,xml){
            return new Grid(id,opt,xml);
        }
    });
});

